package com.lyfam.game.geometry;

/**
 * @author dmly
 * 
 * This class represent the geometry vector and its basic calculation.
 * 
 */
public class Vector2D
{

	private float x, y;

	public float getX()
	{
		return x;
	}

	public void setX(float x)
	{
		this.x = x;
	}

	public float getY()
	{
		return y;
	}

	public void setY(float y)
	{
		this.y = y;
	}

	public Vector2D()
	{
		x = 0;
		y = 0;
	}

	public Vector2D(float x, float y)
	{
		this.x = x;
		this.y = y;
	}

	public float getLengthSquare()
	{
		return x * x + y * y;
	}

	public float getLength()
	{
		return (float) Math.sqrt(x * x + y * y);
	}

	public void add(Vector2D v)
	{
		x += v.getX();
		y += v.getY();
	}

	public void sub(Vector2D v)
	{
		x -= v.getX();
		y -= v.getY();
	}

	public void mult(float n)
	{
		x *= n;
		y *= n;
	}

	public void div(float n)
	{
		x /= n;
		y /= n;
	}

	public void normalize()
	{
		float m = getLength();
		if (m > 0)
		{
			div(m);
		}
	}

	public static Vector2D clone(Vector2D v)
	{
		return new Vector2D(v.getX(), v.getY());
	}

	public static Vector2D getNormalize(Vector2D v)
	{
		Vector2D clone = Vector2D.clone(v);
		float m = v.getLength();
		if (m > 0)
		{
			clone.div(m);
		}
		
		return clone;
	}

	public void limit(float max)
	{
		if (getLength() > max)
		{
			normalize();
			mult(max);
		}
	}

	public Vector2D perp()
	{
		return new Vector2D(-y, x);
	}

	public float distance(Vector2D v)
	{
		float yDistance = v.getY() - y;
		float xDistance = v.getX() - x;
		return (float) Math.sqrt(yDistance * yDistance + xDistance * xDistance);
	}

	public float distanceSquare(Vector2D v)
	{
		float yDistance = v.getY() - y;
		float xDistance = v.getX() - x;
		return (float) (yDistance * yDistance + xDistance * xDistance);
	}

	public float dot(Vector2D v)
	{
		return x * v.x + y * v.y;
	}

	public int sign(Vector2D v)
	{
		if (y * v.x > x * v.y)
		{
			return -1;
		} else
		{
			return 1;
		}
	}

	public float heading2D()
	{
		float angle = (float) Math.atan2(-y, x);
		return -1 * angle;
	}

	public static void wrapAround(Vector2D v, float maxX, float maxY)
	{
		if (v.getX() > maxX)
		{
			v.setX(0.0f);
		}

		if (v.getX() < 0)
		{
			v.setX(maxX);
		}

		if (v.getY() > maxY)
		{
			v.setY(0);
		}

		if (v.getY() < 0)
		{
			v.setY(maxY);
		}
	}

	public static boolean isInsideRegion(Vector2D v, float left, float top,
			float right, float bottom)
	{
		return !((v.x < left) || (v.x > right) || (v.y < top) || (v.y > bottom));
	}
}
